package botTicTacToe;

public class GameBot {
	private GameTree game;
	private int side;
	int nextTurn;
	
	public GameBot(int side) {
		this.side = side;
		game = null;
	}
	
	public void init(int nextTurn) {
		if (inited()) return;
		game = new GameTree();
		game.generateMap(nextTurn);
		this.nextTurn = nextTurn;
	}
	
	public boolean inited() {
		return (!(game == null));
	}
	
	public void init(GameField field, int nextTurn) {
		if (inited()) return;
		game = new GameTree(field);
		game.generateMap(nextTurn);
		this.nextTurn = nextTurn;
	}
	
	public GameField getField() {
		return game.getCurrentField();
	}
	
	public void turn(int x, int y) {
		if (!inited()) return;
		game.turn(nextTurn, x, y);
		nextTurn = nextTurn == GameField.MARK_X? GameField.MARK_O : GameField.MARK_X;
	}
	
	public void turn(int cellN) {
		if (!inited()) return;
		game.turn(nextTurn, cellN);
		nextTurn = nextTurn == GameField.MARK_X? GameField.MARK_O : GameField.MARK_X;
	}
	
	public int getTurn() {
		if (!inited()) return -1;
		if (game.getCurrentField().isGameEnd()) return -1;
		int cellN = 0;
		float maxPriority = 0;
		for (int i = 0; i < GameField.CELL_NUMBER; i++) {
			if (game.getCurrentField().getCell(i) != GameField.MARK_NONE) continue;
			GameField childField = null;
			try {
				childField = game.getCurrentField().clone();
			} catch (CloneNotSupportedException e) {
				e.printStackTrace();
			}
			childField.setMark(nextTurn, i);
			float priority = computePriority(childField);
			if (priority > maxPriority) {
				maxPriority = priority;
				cellN = i;
			}
		}
		return cellN;
	}
	
	private float computePriority(GameField field) {
		float minPriority = 1;
		// If bot wins then it will choose this position
		if (field.getWinner() == side) return minPriority+1;
		// Bot uses pessimistic strategy
		// It computes the best minimal priority of the cell,
		// so it would be the best cell in the worst-case scenario
		for (int i = 0; i < GameField.CELL_NUMBER; i++) {
			if (field.getCell(i) != GameField.MARK_NONE) continue;
			GameField childField = null;
			try {
				childField = field.clone();
			} catch (CloneNotSupportedException e) {
				e.printStackTrace();
			}
			childField.setMark(nextTurn == GameField.MARK_X? GameField.MARK_O : GameField.MARK_X, i);
			GameTree.GameNode child = game.getNode(childField);
			if (child == null) continue;
			int winsX = child.getWinsX();
			int winsO = child.getWinsO();
			int draws = child.getDraws();
			float priority;
			if (side == GameField.MARK_X) priority = 1 - winsO / (float)(winsX + winsO + draws);
			else priority = 1 - winsX / (float)(winsX + winsO + draws);
			if (priority < minPriority) minPriority = priority;
		}
		
		return minPriority;
	}
}
